package com.webinsky.service.catalog.impl;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.webinsky.common.proj.DelFlag;
import com.webinsky.common.proj.Lang;
import com.webinsky.common.utils.db.Pagnation;
import com.webinsky.domain.catalog.Catalog;
import com.webinsky.domain.catalog.Tag;
import com.webinsky.domain.catalog.Tags;
import com.webinsky.persist.dao.catalog.TagMapper;
import com.webinsky.persist.dao.catalog.TagcatMapper;
import com.webinsky.persist.entity.catalog.TagFilter;
import com.webinsky.persist.entity.catalog.Tagcat;
import com.webinsky.service.catalog.TagManagement;

@Service
public class TagManagementImpl implements TagManagement {
	@Autowired
	private TagMapper tagDao;
	@Autowired
	private TagcatMapper tagcatDao;
	
	private com.webinsky.persist.entity.catalog.Tag convert(Tag tag){
		com.webinsky.persist.entity.catalog.Tag t = new com.webinsky.persist.entity.catalog.Tag();
		t.setLanguage(tag.getCatalog().getLang().getLang());
		t.setName(tag.getName());
		t.setTagcatId(tag.getCatalog().getId());
		return t;
	}
	
	private Tag convert(com.webinsky.persist.entity.catalog.Tag tag, Tagcat tagcat){
		Tag t = new Tag();
		t.setId(tag.getId());
		t.setName(tag.getName());
		t.setLang(Lang.parse(tag.getLanguage()));
		if ( tagcat != null ){
			Catalog catalog = new Catalog();
			catalog.setSiteId(tagcat.getSiteId());
			catalog.setId(tagcat.getId());
			catalog.setLang(Lang.parse(tagcat.getLanguage()));
			catalog.setName(tagcat.getName());
			t.setCatalog(catalog);
		}
		return t;
	}
	
	@Override
	public void create(Tag tag) {
		if ( tag != null ){
			if ( tag.getCatalog() != null ){
				Tagcat tagcat = tagcatDao.selectById(tag.getCatalog().getId());
				if ( tagcat != null ){
					com.webinsky.persist.entity.catalog.Tag t = convert(tag);
					t.setDel(DelFlag.UNDel.getFlag());
					int count = tagDao.selectCount();
					t.setSort(count + 1);
					tagDao.insert(t);
					tag.setId(t.getId());
				}
			}
		}
	}

	@Override
	public void update(Tag tag) {
		if ( tag != null ){
			com.webinsky.persist.entity.catalog.Tag t = tagDao.selectById(tag.getId());
			if ( t != null ){
				t.setName(tag.getName());
				tagDao.updateByPrimaryKey(t);
			}
		}
	}

	@Override
	public void delete(int id) {
		if ( id > 0 ){
			com.webinsky.persist.entity.catalog.Tag t = tagDao.selectById(id);
			if ( t != null ){
				t.setDel(DelFlag.Del.getFlag());
				tagDao.updateByPrimaryKey(t);
			}
		}
	}

	@Override
	public Tags getTagsPagnation(int start, int size) {
		Pagnation pagnation = new Pagnation();
		pagnation.setPageSize(size);
		pagnation.setPageStart(start);
		List<com.webinsky.persist.entity.catalog.Tag> tags = tagDao.selectByPagnation(pagnation);
		List<Integer> tagIds = tags.stream().map(tag -> tag.getId()).collect(Collectors.toList());
		List<Tagcat> tagcats = tagcatDao.selectByIds(tagIds);
		Map<Integer, Tagcat> idTagcatMap = tagcats.stream().collect(Collectors.toMap(Tagcat::getId, Function.identity()));
		int count = tagDao.selectCount();
		Tags ts = new Tags();
		ts.setTotalSize(count);
		tags.forEach(e -> {
			ts.getTags().add(convert(e, idTagcatMap.get(e.getTagcatId())));
		});
		return ts;
	}

	@Override
	public Tags getTagsByName(int tagcatId, String name, int siteId, Lang lang, int start, int size) {
		Tags ts = new Tags();
		TagFilter filter = new TagFilter();
		filter.setPageSize(size);
		filter.setPageStart(start);
		filter.setName(name);
		filter.setTagcatId(tagcatId);
		filter.setSiteId(siteId);
		filter.setLang(lang.getLang());
		List<com.webinsky.persist.entity.catalog.Tag> tags = tagDao.selectByTagcatFilter(filter);
		int count = tagDao.selectCountByFilter(filter);
		List<Integer> tagcatIds = tags.stream().map(e -> e.getTagcatId()).collect(Collectors.toList());
		List<Tagcat> tagcats = tagcatDao.selectByIds(tagcatIds);
		Map<Integer, Tagcat> tagcatMap = tagcats.stream().collect(Collectors.toMap(Tagcat::getId, Function.identity()));
		tags.forEach(element -> {
			ts.getTags().add(convert(element, tagcatMap.get(element.getTagcatId())));
		});
		ts.setTotalSize(count);
		return ts;
	}

	@Override
	public void create(List<Tag> tags) {
		if ( tags != null ) {
			tags.forEach(tag -> create(tag));
		}
		
	}

	@Override
	public void update(List<Tag> tags) {
		if ( tags != null ){
			tags.forEach( e -> update(e) );
		}
	}

	@Override
	public Tags getTagsByIds(List<Integer> ids) {
		if ( ids == null || ids.isEmpty() ){
			return null;
		}
		List<com.webinsky.persist.entity.catalog.Tag> tags = tagDao.selectByIds(ids);
		if ( tags.isEmpty() ){
			return null;
		}
		List<Integer> catalogIds = tags.stream().map(e -> e.getTagcatId()).collect(Collectors.toList());
		List<Tagcat> tagcats = tagcatDao.selectByIds(catalogIds);
		if ( tagcats.isEmpty() ){
			return null;
		}
		Map<Integer, Tagcat> tagcatMap = tagcats.stream().collect(Collectors.toMap(Tagcat::getId, Function.identity()));
		Tags resultTags = new Tags();
		tags.forEach(t -> {
			Tag rTag = new Tag();
			rTag.setId(t.getId());
			rTag.setName(t.getName());
			rTag.setLang(Lang.parse(t.getLanguage()));
			if ( tagcatMap.get(t.getTagcatId()) != null ){
				Tagcat tagcat = tagcatMap.get(t.getTagcatId());
				Catalog catalog = new Catalog();
				catalog.setId(t.getTagcatId());
				catalog.setName(tagcat.getName());
				catalog.setSiteId(tagcat.getSiteId());
				catalog.setLang(Lang.parse(tagcat.getLanguage()));
				rTag.setCatalog(catalog);
			}			
			resultTags.getTags().add(rTag);
		});
		return resultTags;
	}

}
